/***
 * 封装富文本的各类核心处理API
 * 如：修饰执行前后的修饰拦截、拆分提取选择元素，循环选区元素，右键菜单等等
 * 封装列表回车核心分析处理逻辑，多页模式结构处理
 * by kevin.huang
 * ****/
Keditor.extend({
    beforeExecute: function (fn, params, eventEl) {
        let go = this.tableIns.exeCss(fn, params, eventEl);       
        if (go) {
            let neefFocus = !eventEl || $B.Dom.attr(eventEl,"focus");
            if(neefFocus){
                if(!this.hasFocus()){
                    $B.alert({
                        timeout:1.5,
                        position:'top',
                        mask:false,
                        content:editCfg.label.pleaseFocus
                    });
                    return false;
                }               
            }
            if (this.toolIns && this.toolIns.needRegion(fn)) {
                if (this.cssEls.length === 0) {
                    this.getCssEls();
                }
            }
            if (this.cssPEls.length === 0) {
                this.getCssEls(true);
            }
            return true;
        }
        return false;
    },
    afterExecute: function (fn, params, eventEl) {
    },
    /**
     * 高亮选择的段落
     * ***/
    activedLinePELS: function () {
        if (this.cssPEls.length === 0) {
            this.getCssEls(true);
        }
        this.loopPelCssEls(($p) => {
            $B.DomUtils.addClass($p, "k_editor_actived_section");
        });
    },
    /**
     * 取消高亮选择的段落
     * ***/
    unactivedLinePELS: function () {
        this.loopPelCssEls(($p) => {
            $B.DomUtils.removeClass($p, "k_editor_actived_section");
        });
    },
    _getRootPel: function ($p1, retObj) {
        var $pp = $p1;
        while ($pp) {
            if ($B.DomUtils.hasClass($pp.parentNode, "k_edit_input")) {
                break;
            }
            $pp = $pp.parentNode;
            if (retObj) {
                if ($pp.nodeName === "TD") {
                    if (!retObj["isInTd"]) {
                        retObj["isInTd"] = true;
                        retObj["td"] = $pp;
                    }
                } else if ($pp.nodeName === "TABLE") {
                    if (!retObj["table"]) {
                        retObj["table"] = $pp;
                    }
                }
            }
        }
        return $pp;
    },
    _getPelbychild: function ($s) {
        let $p = $s;
        while ($p) {
            if ($B.DomUtils.hasClass($p, "p_element")) {
                break;
            }
            $p = $p.parentNode;
        }
        return $p;
    },
    /**
     * 循环span修饰元素
     * **/
    loopSpanCssEls: function (fn) {
        for (let i = 0, len = this.cssEls.length; i < len; i++) {
            let el = this.cssEls[i];
            fn(el);
            let childs = el.children;
            for (let j = 0; j < childs.length; j++) {
                fn(childs[j]);
            }
        }
    },
    /**
     * 循环段落修饰元素
     * **/
    loopPelCssEls: function (fn) {
        for (let i = 0, len = this.cssPEls.length; i < len; i++) {
            fn(this.cssPEls[i]);
        }
    },
    /**
     * 根据划选的区域分析形成待修饰的tag集合
     * @param not2span 不需要提取span
     * **/
    getCssEls: function (not2span) {
        //console.log("getCssEls");
        if (!this.region) {
            return;
        }
        this.clearCssEls();
        var r = this.region,
            $s1, $s2,
            $p1, $p2;

        $p1 = $B.DomUtils.findbyId(this.$pageWap, r.startPel);
        $p2 = $p1;
        if (r.startPel !== r.endPel) {
            $p2 = $B.DomUtils.findbyId(this.$pageWap, r.endPel);
        }
        if (r.isCollapsed) { //无选区
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            this.cssEls.push($s1);
            this.cssPEls.push($p1);
        } else {
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            if (r.startSpan === r.endSpan) {
                //根据划选下标形成span元素组合 ,并将组合后的span放到 this.cssEls  
                if (!not2span) {
                    let rets = this.splitWrapText($s1, r.startIdx, r.endIdx);
                    let regionEl = this._insertCssSpanEls($s1, rets);
                    this.setRegionByEl(regionEl);
                }
                this.cssPEls.push($p1);
            } else {//跨标签场景，涵盖跨段落场景 
                $s2 = $B.DomUtils.findbyId($p2, r.endSpan);
                let startRegEl = $s1;
                let endRegEl = $s2;
                if (!not2span) {
                    let rets = this.splitWrapText($s1, r.startIdx, $s1.innerText.length);
                    startRegEl = this._insertCssSpanEls($s1, rets);
                    let rets2 = this.splitWrapText($s2, 0, r.endIdx);
                    endRegEl = this._insertCssSpanEls($s2, rets2);
                    this.setRegionByEl(startRegEl, endRegEl);
                    //加入开始选区同级元素
                    let $el = rets;
                    if (Array.isArray(rets)) {
                        $el = rets[rets.length - 1];
                    }
                    let isInSampleP = false;
                    let nextEl = $el.nextSibling;
                    while (nextEl) {
                        if (nextEl === endRegEl) {
                            isInSampleP = true;
                            break;
                        }
                        this.cssEls.push(nextEl);
                        nextEl = nextEl.nextSibling;
                    }
                    //加入结束区域同级元素，需要判断是否是同一个段落的
                    //不在同一个段落才需要做加入
                    if (!isInSampleP) {
                        $el = rets2;
                        if (Array.isArray(rets2)) {
                            $el = rets2[0];
                        }
                        let prevEl = $el.previousSibling;
                        while (prevEl) {
                            this.cssEls.push(prevEl);
                            prevEl = prevEl.previousSibling;
                        }
                    }
                }
                //通过开始，结束选区的标签来处理父级跨选区的span提取加入
                //首先通过提取开始，结束标签所在的段落标签，及其段落标签是容器是否在td单元格范围内，如果是考虑跨表格情况
                let startInfo = {}, endInfo = {};
                let $startPel = this._getRootPel(startRegEl, startInfo);//开始段落
                let $endPel = this._getRootPel(endRegEl, endInfo);//结束段落

                if (!startInfo.isInTd && !endInfo.isInTd) { //选区开始位置，结束位置均不在表格范围内                    
                    this.setbetweenRegion($startPel, $endPel, not2span);
                } else if (startInfo.isInTd && !endInfo.isInTd) { //开始位置在表格内，结束位置不在表格内
                    this.setParentStartRegion(startRegEl, $startPel, $endPel, not2span);
                } else if (!startInfo.isInTd && endInfo.isInTd) { //开始位置不在表格内，结束位置在表格内
                    this.setParentEndRegion(endRegEl, $startPel, $endPel, not2span);
                } else {//开始位置，结束位置均在表格内，
                    if (startInfo.td === endInfo.td) {//同一个单元格内
                        let $startP = this._getPelbychild(startRegEl);
                        let $endP = this._getPelbychild(endRegEl);
                        this.setbetweenRegion($startP, $endP, not2span);
                    }
                }
            }
        }
    },
    setParentEndRegion: function (endRegEl, $startPel, $endPel, not2span) {
        this.setbetweenRegion($startPel, $endPel, not2span);
        this.loopParentRegionEl(endRegEl, $endPel, 'previousSibling', not2span);
    },
    /**
     *嵌套元素场景下，父元素选区提取
     * ***/
    setParentStartRegion: function (startEl, $startPel, $endPel, not2span) {
        //提取开始段落的选区
        this.loopParentRegionEl(startEl, $startPel, 'nextSibling', not2span);
        this.setbetweenRegion($startPel, $endPel, not2span);
    },
    setbetweenRegion: function ($startPel, $endPel, not2span) {
        if ($B.DomUtils.hasClass($startPel, "p_element")) {
            this.cssPEls.push($startPel);
        }
        if ($startPel !== $endPel) {
            let nextEl = $startPel.nextSibling;
            while (nextEl) {
                if (nextEl === $endPel) {
                    break;
                }
                if ($B.DomUtils.hasClass(nextEl, "p_element")) {
                    this.cssPEls.push(nextEl);
                }
                this.putPelChilds2CssEls(nextEl, not2span);
                nextEl = nextEl.nextSibling;
            }
            if ($B.DomUtils.hasClass($endPel, "p_element")) {
                this.cssPEls.push($endPel);
            }
        }
    },
    loopParentRegionEl: function (startEl, $rootPel, siblingKey, not2span) {
        let $p = startEl.parentNode;
        if ($p === $rootPel) {
            return;
        }
        let nextEl = $p[siblingKey];
        while (nextEl) {
            if ($B.DomUtils.hasClass(nextEl, "p_element")) {
                this.cssPEls.push(nextEl);
            }
            this.putPelChilds2CssEls(nextEl, not2span);
            nextEl = nextEl[siblingKey];
        }
        this.loopParentRegionEl($p, $rootPel, siblingKey, not2span);
    },
    putPelChilds2CssEls: function ($p, not2span) {
        if ($p.firstChild.nodeName === "TABLE") { //是表格
            let table = $p.firstChild;
            let body = table.firstChild;
            let trs = body.children;
            for (let i = 0; i < trs.length; i++) {
                let tds = trs[i].children;
                for (let j = 0; j < tds.length; j++) {
                    let plist = tds[j].children;
                    for (let m = 0; m < plist.length; m++) {
                        this.putPelChilds2CssEls(plist[m]);
                    }
                }
            }
        } else {
            let childs = $p.children;
            if ($B.DomUtils.hasClass($p, "p_element")) {
                let put = true;
                for(let i = 0 ;i < this.cssPEls.length ;i++){
                    if(this.cssPEls[i] === $p){
                        put = false;
                        break;
                    }
                }
                if(put){
                    this.cssPEls.push($p);
                }                
            }
            for (let i = 0; i < childs.length; i++) {
                let $i = childs[i];
                if (!not2span && $i.nodeName === "SPAN" && $B.DomUtils.hasClass($i, "p_span")) {
                    this.cssEls.push($i);
                } else {
                    this.putPelChilds2CssEls($i);
                }
            }
        }
    },
    /**
     * 将开始regin，结束region拆分好的span插入替换到相应的位置
     * ***/
    _insertCssSpanEls: function ($s1, rets) {
        let regionEl;
        if (Array.isArray(rets)) {
            let $firstEl;
            for (let i = 0; i < rets.length; i++) {
                if (i === 0) {
                    $firstEl = rets[i];
                    $B.DomUtils.replace($s1, rets[i]);
                } else {
                    $B.DomUtils.after($firstEl, rets[i]);
                    $firstEl = rets[i];
                }
                if ($B.DomUtils.hasClass(rets[i], "_region_span")) {
                    $B.DomUtils.removeClass(rets[i], "_region_span");
                    regionEl = rets[i];
                    this.cssEls.push(regionEl);
                }
            }
        } else {
            regionEl = rets;
            if ($B.DomUtils.hasClass(regionEl, "_region_span")) {
                $B.DomUtils.removeClass(regionEl, "_region_span");
            }
            this.cssEls.push(rets);
        }
        return regionEl;
    },
    //对标签根据选区进行拆分
    splitWrapText: function ($el, start, end) {
        let text = $el.innerText;
        let len = text.length;
        //先处理不可见字符，纠正start，end下标
        if (text[0] === "\u200B") {
            text = text.replace("\u200B", "");
            if (start > 0) {
                start = start - 1;
            }
            end = end - 1;
        }
        if (text[len - 1] === "\u200B") {
            text[len - 1] = "";            
            if (end === len) {
                end = end - 1;
            }
        }
        len = text.length;
        if (len === end && start === 0) {
            $B.DomUtils.addClass($el, "_region_span");
            setTimeout(()=>{
                $B.DomUtils.removeClass($el, "_region_span");
            },666);
            return $el;
        }
        let cssObj = $B.style2cssObj($el);
        let ret = [], txt, $span;
        if (start > 0) {
            txt = text.slice(0, start);
            $span = this.createSpanEl();
            $B.DomUtils.css($span, cssObj);
            $span.innerText = "\u200B" + txt;
            ret.push($span);
        }
        //这个是选区span
        $span = this.createSpanEl();
        $B.DomUtils.addClass($span, "_region_span");
        txt = text.slice(start, end);
        $span.innerText = "\u200B" + txt;
        $B.DomUtils.css($span, cssObj);
        ret.push($span);
        if (len > end) {
            txt = text.slice(end, len);
            $span = this.createSpanEl();
            $span.innerText = "\u200B" + txt;
            ret.push($span);
            $B.DomUtils.css($span, cssObj);
        }
        setTimeout(()=>{
            for(let i = 0; i < ret.length ;i++){
                $B.DomUtils.removeClass(ret[i], "_region_span");
            }        
        },666);
        return ret;
    },
    /**
     * 根据选区/光标抽取css集合，用于工具栏联动
     * ***/
    extractCss: function () {
        let ret = this.getSpanAndPCss();
        var cssSpanMap = ret.spanCss;
        var cssPelMap = ret.pCss;
        let cssMap = $B.extendObjectFn(cssSpanMap, cssPelMap);
        return cssMap;
    },
    getSpanAndPCss:function(){
        var cssSpanMap = UTILS.getSpanDefcss();
        var cssPelMap = UTILS.getPelDefCss();        
        var r = this.region, $p1, $p2, isCrossPel = r.startPel !== r.endPel, $s1, $s2;
        $p1 = $B.DomUtils.findbyId(this.$pageWap, r.dirStrtId);
        $p2 = $p1;
        if (isCrossPel) {
            $p2 = $B.DomUtils.findbyId(this.$pageWap, r.dirEndId);
        }
        if (r.isCollapsed) { //无选区
            UTILS.extractPcss($p1, cssPelMap);//先提取行样式
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            UTILS.extractSpancss($s1, cssSpanMap);
        } else {//存在选区
            if (isCrossPel) { //跨段落
                UTILS.extractPcss($p1, cssPelMap);//先提取行样式
                $s1 = $B.DomUtils.findbyId($p1, r.startSpan);//提取开始行里面的span选区
                UTILS.extractSpancss($s1, cssSpanMap);
                let nextPel = $p1.nextSibling;
                while (nextPel) {
                    if (nextPel === $p2) { //结束段落
                        UTILS.extractPcss(nextPel, cssPelMap);//先提取行样式
                        $s2 = $B.DomUtils.findbyId(nextPel, r.endSpan);
                        let $1 = nextPel.firstChild;
                        while ($1) {
                            UTILS.extractSpancss($1, cssSpanMap);
                            if ($1 === $s2) {
                                break;
                            }
                            $1 = $1.nextSibling;
                        }
                    } else {//中间段落
                        UTILS.extractPcss(nextPel, cssPelMap);//先提取行样式
                        let childs = nextPel.children;
                        for (let i = 0; i < childs.length; i++) {
                            UTILS.extractSpancss(childs[i], cssSpanMap);
                        }
                    }
                    nextPel = nextPel.nextSibling;
                }
            } else {//同一个段落
                UTILS.extractPcss($p1, cssPelMap);//先提取行样式
                $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                if (r.startSpan !== r.endSpan) { //跨标签
                    $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                    $s2 = $B.DomUtils.findbyId($p1, r.endSpan);
                    while ($s1) {
                        UTILS.extractSpancss($s1, cssSpanMap);
                        if ($s1 === $s2) {
                            break;
                        }
                        $s1 = $s1.nextSibling;
                    }
                } else {//同一个标签内                   
                    $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                    UTILS.extractSpancss($s1, cssSpanMap);
                }
            }
        }
        return {spanCss:cssSpanMap,pCss:cssPelMap};
    },
    /**
     * 获取一个段落元素
     * ***/
    createPEl: function () {
        return UTILS.createPEl();
    },
    createSpanEl: function () {
        return UTILS.createSpanEl();
    },
    loopUpdateId: function (el) {
        var id = $B.generateDateUUID();
        el.id = id;
        var childs = el.children;
        for (let i = 0; i < childs.length; i++) {
            if (childs[i].tagName !== "BR") {
                this.loopUpdateId(childs[i]);
            }
        }
    },
    /**
     * 在$p段落后插入一行，返回该行对象
     * @param $p 
     * @param flag  不需要span元素 
     */
    insertNewPAfter: function ($p, flag) {
        let newel = UTILS.createPEl(flag);
        $B.DomUtils.after($p, newel);
        return newel;
    },
    /***
     * 移除span嵌套
     * **/
    removeNestSpan: function ($el) {
        if ($el.tagName === "SPAN") {

        } else {
            var childs = $el.children;
            for (let i = 0; i < childs.length; i++) {
                this.removeNestSpan(childs[i]);
            }
        }
    },
    changeSelectionColor: function (cssName, cssValue) {
        if (!this.$docHeader) {
            this.$docHeader = document.getElementsByTagName('head')[0];
        }
        var extCss = "";
        if (cssName === "color") {
            extCss = ";background-color:#3390FF;";
        }
        var style = '.k_edit_input *::selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}' +
            '.k_edit_input *::-moz-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}' +
            '.k_edit_input *::-webkit-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}';
        var $t = $B.DomUtils.findbyId(this.$docHeader, "#_selection_style");
        if ($t) {
            this.$docHeader.removeChild($t);
        }
        var snode = document.createElement("style");
        snode.id = "_selection_style";
        snode.type = "text/css";
        if (snode.styleSheet) {
            snode.styleSheet.cssText = style;
        } else {
            snode.innerHTML = style;
        }
        this.$docHeader.appendChild(snode);
    },
    clearSelectionColor: function () {
        if (this.$docHeader) {
            var $t = $B.DomUtils.findbyId(this.$docHeader, "#_selection_style");
            if ($t) {
                this.$docHeader.removeChild($t);
            }
        }
    },
    /**
     * 循环元素里面span标签
     * **/
    loopPelSapn: function ($el, fn) {
        let childs = $el.children;
        for (let i = 0; i < childs.length; i++) {
            let child = childs[i];
            if (child.tagName === "SPAN") {
                fn(child);
            } else {
                this.loopPelSapn(child, fn);
            }
        }
    },
    hideCtxMenu: function () {
        if (this.$ctxMenu) {
            this.$ctxMenu.style.display = "none";
        }
    },
    showCtxMenu: function (pos) {
        if (!this.$ctxMenu) {
            let opts = {
                title: "",
                onClosed: ($l) => {
                    this.hideCtxMenu();
                },
                onCreated: ($b) => {
                    let ctxMenus = editCfg.ctxMenus;
                    UTILS.createCtxItem(ctxMenus,$b,(el,e)=>{
                        this.hideCtxMenu();
                        let fn = $B.Dom.attr(el, "fn");
                        if (this[fn]) {
                            this[fn](e);
                        }else{
                            console.log(fn + " is not found");
                        }
                    });                  
                    this.bindFocusEv($b);
                }
            };
            this.$ctxMenu = UTILS.createCommPanel(opts);
        }
        UTILS.showPanel(this.$ctxMenu,pos);
    },
    openInsertTable: function () {
        this.tableIns.openInsertTable((prs) => {
            this.insertTableFn(prs);
        });
    },
    openInsertFile: function (e) {
        this.toolIns.uploadFnMaker("uploadFn",{top:e.pageY - 20,left:e.pageX-10} );
    },
    openInsertImage: function (e) {
        this.invokeToolMaker("pictureFn", e);
    },
    openInsertLink: function (e) {
        this.invokeToolMaker("linkFn", e);
    },
    onOpenLinkPanel: function ($b) {
        let r = this.getRegion();
        if (!r.isCollapsed) {
            if (r.dirStrtId !== r.dirEndId) {
                $B.alert({
                    content: editCfg.label.unsuport,
                    timeout: 2,
                    onClosed: () => {
                        this.toolIns.hidePanel();
                    }
                });
                return false;
            }
            let $name = $B.Dom.findbyId($b, "_link_name");
            let $addr = $B.Dom.findbyId($b, "_addr_url");
            this.getCssEls();
            let firstEl = this.cssEls[0];
            let txt = [];
            txt.push(firstEl.innerText);
            let rms = [];
            if (this.cssEls.length > 1) {
                let i = 1;
                while (i < this.cssEls.length) {
                    txt.push(this.cssEls[i].innerText);
                    i++;
                    rms.push(this.cssEls[i]);
                }
            }
            $name.value = txt.join("");
        }
    },
    openInsertEmotion: function () {

    },
    openGraph: function (e) {
       this.toolIns.paragraphFnMaker("paragraphFn",{top:e.pageY - 60,left:e.pageX-10} );
    },
    invokeToolMaker: function (fn, e) {
        let pos = {
            top: e.pageY,
            left: e.pageX
        };
        let method = fn + "Maker";
        this.toolIns[method](fn, pos);
    },
    showLinkMenu: function (el) {
        if (!this.$linkMenu) {
            let opts = {
                title: "",
                onClosed: ($l) => {
                    this.hidenLinkMenu();
                },
                onCreated: ($b) => {
                    let $f = $B.Dom.createEl(editCfg.linkMenu);
                    $B.Dom.append($b, $f);
                    this.bindFocusEv($b);
                    $B.Dom.click($B.Dom.findbyId($f, "_del_link"), (e) => {
                        if (this.curLinkTag) {
                            let el = this.curLinkTag.parentNode;
                            el.innerText = "\u200b";
                            $B.Dom.removeAttr(el,"contenteditable");
                            this.setRegionByEl(el, el, 1);
                        }
                        this.hidenLinkMenu();
                    });
                }
            };
            this.$linkMenu = UTILS.createCommPanel(opts);
        }
        if (el.nodeName === "SPAN") {
            el = el.firstChild;
        }
        let href = $B.Dom.attr(el, "href");
        let txt = el.innerText;
        let $a = $B.Dom.findbyId(this.$linkMenu, "_op_link");
        $a.href = href;
        $a.innerText = txt;
        let pos = $B.Dom.offset(el);
        pos.top = pos.top + 22;
        pos.left = pos.left + $B.Dom.width(el) - 8;      
        UTILS.showPanel(this.$linkMenu,pos);
        this.curLinkTag = el;
    },
    hidenLinkMenu: function () {
        this.curLinkTag = undefined;
        if (this.$linkMenu) {
            this.$linkMenu.style.display = "none";
        }
    },
    showImgMenu:function(el,e){        
        if(el.nodeName === "SPAN"){
            el = el.firstChild;
        }
        if(e.which === 3){
            if (!this.$imgMenu) {
                let opts = {
                    title: "",
                    onClosed: ($l) => {
                        this.hidenImgMenu();
                    },
                    onCreated: ($b) => {
                        let ctxMenus = editCfg.imgMenus;
                        UTILS.createCtxItem(ctxMenus,$b,(el,e)=>{
                            this.hidenImgMenu(); 
                            let fn = $B.Dom.attr(el, "fn");
                            if (this[fn]) {
                                this[fn](e);
                            }else{
                                console.log(fn + " is not found");
                            }
                        });                      
                        this.bindFocusEv($b);                       
                    }
                };
                this.$imgMenu = UTILS.createCommPanel(opts);
            }
            let pos = $B.Dom.offset(el);
            let w = $B.Dom.outerWidth(el);
            let h = $B.Dom.outerHeight(el);
            pos.top = pos.top + h;
            pos.left = pos.left + w;
            UTILS.showPanel(this.$imgMenu,pos);
            this.curImgTag = el;
            clearTimeout(this.clearCurImgTimer);
        }else{//拖拉调整
            this.ResizeIns.bind(el);
        }
    },
    editImgFn:function(e){
        clearTimeout(this.clearCurImgTimer);             
        let $fb = this.toolIns.editImgMaker("pictureEditFn",{top:e.pageY - 30,left:e.pageX -40});
        let w = $B.Dom.width(this.curImgTag);
        let h = $B.Dom.height(this.curImgTag);
        let paddingTop = $B.Dom.css(this.curImgTag,"padding-top");
        let paddingRight = $B.Dom.css(this.curImgTag,"padding-right");
        let paddingBottom = $B.Dom.css(this.curImgTag,"padding-bottom");
        let paddingLeft = $B.Dom.css(this.curImgTag,"padding-left");
        let $top = $B.Dom.findbyId($fb,"_top_k_padding");
        let $bottom = $B.Dom.findbyId($fb,"_bottom_k_padding"); 
        let $left = $B.Dom.findbyId($fb,"_left_k_padding");
        let $right = $B.Dom.findbyId($fb,"_right_k_padding");
        let $width = $B.Dom.findbyId($fb,"_img_width");
        let $height = $B.Dom.findbyId($fb,"_img_height");
      
        $top.value = paddingTop;
        $right.value = paddingRight;
        $bottom.value = paddingBottom;
        $left.value = paddingLeft;
        w = w - paddingLeft - paddingRight;
        h = h - paddingTop - paddingBottom;
        $width.value = w;
        $height.value = h ;
    },
    borderImgFn:function(e){        
        clearTimeout(this.clearCurImgTimer);
        let $fb = this.toolIns.borderImgMaker("pictureBorderFn",{top:e.pageY - 50,left:e.pageX -50});
    },
    hidenImgMenu:function(el){  
        clearTimeout(this.clearCurImgTimer);
        this.clearCurImgTimer = setTimeout(()=>{
            this.curImgTag = undefined;            
        },500);             
        if (this.$imgMenu) {
            this.$imgMenu.style.display = "none";
        }
    },
    deleteImgFn:function(){
        if( this.curImgTag){
            let prt = this.curImgTag.parentNode;
            this.curImgTag = undefined;           
            prt.innerHTML = "\u200b";
            $B.Dom.removeAttr(prt,"contenteditable");
            this.move2end(prt);
        }
    }, 
    clearHtmlStr: function (contents) {
        if (contents !== "") {
            contents = contents.replace(/[\n\r]/g, '').replace(/\s+</g, "<").replace(/>\s+/g, ">").replace(/(^\s*)|(\s*$)/g, "");
        }
        return contents;
    },
    createImage: function (prs) {
        if (typeof prs.width === "undefined") {
            prs.width = "auto";
        }
        if (typeof prs.height === "undefined") {
            prs.height = "auto";
        }
        let $img = $B.Dom.createEl("<img id='" + $B.getUUID() + "' tabindex='0' src='" + prs.url + "' style='width:" + prs.width + "px;height:" + prs.height + "px' />");
        return $img;
    },
    createLinkA:function(params){
        let $img = $B.Dom.createEl("<a id='" + $B.getUUID() + "' tabindex='0' href='" + params.url + "' target='_blank' >"+params.name+"</a>");
        return $img;
    },
    callOffBrush:function(){       
        if(this.$brushBtn){
            $B.Dom.removeClass(this.$brushBtn.firstChild,"k_edit_brush_actived")
        }        
        this.BrushingCSS = undefined;
        if(this.$movingBrushMouseEl){
            this.$movingBrushMouseEl.style.display = "none";
        }
    },
    bindTableEvents($tab){
        
        this.tableIns.bindEvents($tab);
    },
    /**
     * 检查分析段落是否为list（数值，图标样式）
     * return ""
     * **/
    anyliscList($p){
        while($p){
            if($p.nodeName === "DIV"){
                break;
            }
            $p = $p.parentNode;
        }
        let $s = $p.firstChild;         
        if($s.nodeName === "SPAN"){            
            let txt = $s.innerText;
            txt = txt.replaceAll("\u200b","");
            let mats = this.matchSEQReg(txt);
            if(mats){                
                let idxText = mats[0];
                let num = mats[2];
                let numNext = parseInt(num) + 1;
                let nextIdx = idxText.replace(num,numNext);
                let ret = {
                    num: true,
                    nextIdx: nextIdx
                };
                if(!/^(\s*)(\d+)\s*[、.]\s*$/.test(txt)){
                    ret["prePel"] = $p;
                    ret["idxText"] = idxText;
                }
                return ret;
            }
        }
    },
    matchSEQReg(txt){
        txt = txt.replace(/\u200b/,"");
        let mats = txt.match(/^(\s*)(\d+)\s*[、.\)）]\s*/);
        return mats;
    },
    /**
     * 回车更新序列
     * **/
    updateListSeq($p,prs){
        if(prs.num || prs.zhNum){
            let $nextP = $p;
            while($nextP){
                let $s = $nextP.firstChild;
                if($s.nodeName !== "SPAN"){
                    break;
                }
                let txt = $s.innerText.replace(/\u200b/,"");
                let mats = this.matchSEQReg(txt);
                if(mats){
                    console.log(mats);
                    let idxText = mats[0]; 
                    let num = mats[2];                                                            
                    if(prs.num){
                        //替换数字后检测一下格式是否一致（空格、点号）
                        let stype1 = prs.nextIdx.replace(/\d+/g,"");
                        let stype2 = idxText.replace(/\d+/g,"");
                        if(stype1 !== stype2){//格式不一致
                            break;
                        }
                        let numNext ;
                        if(prs.usePrs){
                            if(prs._curIdx){
                                numNext = prs._curIdx + 1;
                            }else{
                                numNext = parseInt( prs.nextIdx.match(/\d+/));                                
                            }
                            prs._curIdx = numNext;
                        } else{
                            numNext = parseInt(num) + 1;
                        }                       
                        $s.innerText = "\u200b" + idxText.replace(num,numNext);
                    }                   
                }else{
                    break;
                }
                $nextP = $nextP.nextSibling;
            }
        }        
    },
    /**
     * color：颜色
     * fontSize：字体图标大小
     * iconCls：字体样式名称
     * **/
    getFontIconBase64(color,fontSize,iconCode){
        if(!this.$iconCavas){
            let $wap = $B.Dom.createEl('<div style="position:absolute;top:0px;left:0px;"><canvas></canvas><span></span></div>');
            this.$iconCavas = $wap.firstChild;
            this.$iconText = $wap.lastChild;
            $B.Dom.append(document.body,$wap);
            
        }
        this.$iconText.innerHTML = iconCode;
        var width = fontSize;
        var height = width;

        var context = this.$iconCavas.getContext('2d');
        context.fillStyle = color;
        context.font = fontSize + 'px fontello';
        context.fillText(this.$iconText.innerText, 0, height - 2, width);
        var dataURL = this.$iconCavas.toDataURL("image/png");
        console.log(dataURL);
    },
    /**
     * 创建页
     * ***/
    createDocPage(bindEvents){
        let $p = this.createPEl();       
        if(this.opts.mutilPage){ //如果是多页功能
            let pgCfg = editCfg.pagesCfg.prpValues.page;
            let width = parseInt( pgCfg.pageWidth) + 2  ;
            let height = parseInt( pgCfg.pageHeight) + 2 ;
            let $pageWap = $B.Dom.createEl("<div class='k_box_size k_edit_page_wap' style='overflow:visible;width: "+width+"px;height:"+height+"px;margin:15px auto;position: relative; box-shadow: 0 0 5px rgb(0 0 0 / 10%);border: 1px #d3d3d3 solid;background:#fff;position:relative;'></div>");
            let $pageBack = $B.Dom.append($pageWap,"<div style='position:absolute;top:0;left:0;width:100%;height:100%;' class='pg_back_wap k_box_size'></div>");
            let $pageInput = $B.Dom.append($pageWap,"<div style='position:absolute;top:0;left:0;width:100%;height:100%;' class='pg_input_wap k_box_size'><div  spellcheck='false' contenteditable='true' class='k_edit_input _input_field k_box_size' style='width:100%;height:100%;'></div></div>");            
            $B.DomUtils.append($pageInput.firstChild, $p);
            $B.Dom.append($pageWap, "<div id='page_right_eara' class='k_box_size sibar_eara' style='height:100%;display:none;position:absolute;top:0px;right:0px;'><div class='k_box_size _line' style='width:0px;height:0;border-left:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_left_eara'  class='k_box_size sibar_eara' style='height:100%;display:none;position:absolute;top:0px;left:0px;'><div  class='k_box_size _line' style='width:0px;height:0px;border-right:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_top_eara'  class='k_box_size sibar_eara'  style='width:100%;display:none;position:absolute;left:0px;top:0px;'><div  class='k_box_size _line'  style='width:0px;height:0px;border-bottom:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_bottom_eara'  class='k_box_size sibar_eara'  style='width:100%;display:none;position:absolute;left:0px;bottom:0px;'><div  class='k_box_size _line'  style='width:0px;height:0px;border-top:1px dashed #E5E5E5;position:absolute;'></div></div>");
            if(bindEvents){
                setTimeout(()=>{
                    this.bindPageEvents($pageWap);
                },100);
            }
            return $pageWap;
        }
        let $pageWap = $B.Dom.createEl("<div class='k_box_size k_edit_page_wap' style='background:#fff;width:100%;height:100%;padding:2px 2px;overflow: auto;'><div  spellcheck='false' contenteditable='true' class='k_edit_input _input_field k_box_size' style='width:100%;height:100%;'></div></div>");
        $B.DomUtils.append($pageWap.firstChild, $p);
        return $pageWap;
    },
    /**获取富文本主体元素的视窗偏移量***/
    getElObjOfs(){
        if(this._mainofs){
            return this._mainofs;
        }
        this._mainofs = $B.Dom.offset(this.elObj);
        return this._mainofs;
    }
});